"""Add a Minio server to the mix."""
import base64
import contextlib
import os
import typing
from unittest import mock

from . import cluster
from .. import misc
from ..logger import get_logger

LOGGER = get_logger(__name__)


class MinioServer(cluster.KubernetesCluster):
    """Add a Minio server to the mix."""

    @classmethod
    def setUpClass(cls) -> None:
        """Set up the service."""
        super().setUpClass()
        cls.enterClassContext(cls._minio())

    @classmethod
    @contextlib.contextmanager
    def _minio(cls) -> typing.Iterator[None]:
        service_id = 'minio'
        now = misc.now_tz_utc()
        with cls.k8s_namespace(service_id):
            LOGGER.info('Starting Minio')
            secret_data = {
                'aws_access_key_id': 'access_key',
                'aws_secret_access_key': 'secret_key',
            }

            cls.k8s_apply(namespace=service_id, body={
                'apiVersion': 'v1', 'kind': 'Secret',
                'metadata': {'name': service_id},
                'data': {
                    k: base64.b64encode(v.encode('utf8')).decode('ascii')
                    for k, v in secret_data.items()
                },
            })
            cls.k8s_deployment(namespace=service_id, name=service_id, setup_at=now, container={
                'image': 'quay.io/cki/mirror/quay.io/minio/minio:latest',
                'command': ['minio', 'server', '/data'],
                'startupProbe': cls.k8s_startup_probe(9000),
                'env': [
                    {'name': 'MINIO_ROOT_USER_FILE',
                     'value': '/secrets/aws_access_key_id'},
                    {'name': 'MINIO_ROOT_PASSWORD_FILE',
                     'value': '/secrets/aws_secret_access_key'}
                ],
                'volumeMounts': [
                    {'name': 'data', 'mountPath': '/data'},
                    {'name': 'secrets', 'mountPath': '/secrets', 'readOnly': True},
                ],
            }, volumes=[
                {'name': 'data', 'emptyDir': {}},
                {'name': 'secrets', 'secret': {'secretName': service_id}},
            ])
            cls.k8s_service(namespace=service_id, name=service_id)
            if not cls.k8s_wait(namespace=service_id, name=service_id, setup_at=now):
                raise Exception(f'{service_id} did not start up')

            with mock.patch.dict(os.environ, {
                'AWS_ENDPOINT_URL': f'http://{cls.hostname}:9000',
                'AWS_DEFAULT_REGION': 'us-east-1',
                'AWS_ACCESS_KEY_ID': secret_data['aws_access_key_id'],
                'AWS_SECRET_ACCESS_KEY': secret_data['aws_secret_access_key'],
            }):
                yield
